package com.geoai.gcs2.activity

import android.os.Bundle
import android.transition.TransitionManager
import android.util.Log
import android.view.View
import android.view.WindowManager
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.splashscreen.SplashScreen
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.alibaba.android.arouter.launcher.ARouter
import com.geoai.basiclib.base.activity.BaseVVDActivity
import com.geoai.basiclib.engine.dialog.OnDialogSelectWithTypeListener
import com.geoai.basiclib.engine.dialog.showCenterSelectDialogWithType
import com.geoai.basiclib.engine.permission.requestPermission
import com.geoai.basiclib.ext.commContext
import com.geoai.basiclib.ext.drawable
import com.geoai.basiclib.ext.fragmentManager
import com.geoai.basiclib.ext.gone
import com.geoai.basiclib.ext.hideFragment
import com.geoai.basiclib.ext.px2dp
import com.geoai.basiclib.ext.replaceFragment
import com.geoai.basiclib.ext.showFragment
import com.geoai.basiclib.ext.visible
import com.geoai.basiclib.utils.StatusBarUtils
import com.geoai.gcs2.R
import com.geoai.gcs2.activity.mvi.eis.MainActivityEffect
import com.geoai.gcs2.activity.mvi.eis.MainActivityIntent
import com.geoai.gcs2.activity.mvi.eis.MainActivityState
import com.geoai.gcs2.activity.mvi.vm.MainActivityViewModel
import com.geoai.gcs2.databinding.ActivityMainBinding
import com.geoai.modservice.di.ARouterPath
import com.geoai.modservice.di.eventbus.OnHmsFlexVisibility
import com.geoai.modservice.di.eventbus.OnMapClickEvent
import com.geoai.modservice.di.eventbus.OnMapTouchEvent
import com.geoai.modservice.di.eventbus.OnStatusMenuClickEvent
import com.geoai.modservice.di.eventbus.ToggleFpvSize
import com.geoai.modservice.di.eventbus.ToggleMapSize
import com.geoai.modservice.di.eventbus.ToggleSize
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

/**
 * @Author      : Ronny
 * @Email       : Ronny_xie@hotmail.com
 * @Date        : on 2024-04-02 16:16.
 * @Description :
 */
class MainActivity : BaseVVDActivity<MainActivityViewModel, ActivityMainBinding>() {

    override fun hasRegisterEventBus(): Boolean = true

    override fun onCreate(savedInstanceState: Bundle?) {
        window.setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        super.onCreate(savedInstanceState)
    }

    override fun init(savedInstanceState: Bundle?) {
        setStatusBarImmersive()

        replaceFragment(R.id.frameLayoutMap, ARouterPath.PATH_PAGE_MAPVIEW)

        replaceFragment(R.id.frameLayoutTl, ARouterPath.PATH_TOP_STATUS_BAR)

        replaceFragment(R.id.frameLayoutFcStatus, ARouterPath.PATH_CONTROL_FLIGHT_STATUS)

        replaceFragment(R.id.frameLayoutFpv, ARouterPath.PATH_UI_CAMERA_VIDEO)

        replaceFragment(R.id.frameLayoutHms, ARouterPath.PATH_TOP_STATUS_HMS)

        replaceFragment(R.id.frameLayoutObstacle, ARouterPath.PATH_CONTROL_FLIGHT_OBSTACLE)

//        replaceFragment(R.id.frameLayoutOther, ARouterPath.PATH_THIRD_EGG_DROPPER)

        mViewModel.sendUiIntent(MainActivityIntent.BindMenuByLastLaunch)
        mViewModel.sendUiIntent(MainActivityIntent.BindStatusByLastLaunch)

        mBinding.imgSetting.setOnClickListener { mViewModel.sendUiIntent(MainActivityIntent.ShowControlMenuItemSelectorDialog) }
        mBinding.imgSetting.setOnLongClickListener {
            mViewModel.sendUiIntent(MainActivityIntent.ShowStatusMenuItemSelectorDialog)
            true
        }
        mBinding.frameLayoutFpv.setOnClickListener { }
        mBinding.frameLayoutMap.setOnClickListener { }
    }

    private fun setStatusBarImmersive() {
        StatusBarUtils.setStatusBarWhiteText(this)
//        StatusBarUtils.immersive(this)
        StatusBarUtils.hideStatusBar(this)
    }

    override fun startObserve() {
        super.startObserve()
        lifecycleScope.launch {
            mViewModel.uiEffectFlow.collect { effect ->
                when (effect) {
                    is MainActivityEffect.DisplayRLControlMenuSelectorDialog -> displayRlControlMenuSelectorDialog(effect.controlMenuItems)
                    is MainActivityEffect.DisplayRlControlMenuByLastLaunch -> replaceFragment(R.id.frameLayoutRl, effect.aRouterPath)
                    is MainActivityEffect.DisplayLbStatusMenuByLastLaunch -> replaceFragment(R.id.frameLayoutStatus, effect.aRouterPath)
                    is MainActivityEffect.DisplayLbStatusMenuSelectorDialog -> displayLbControlMenuSelectorDialog(effect.controlMenuItems)
                }
            }
        }
        lifecycleScope.launch(Dispatchers.Main) {
            mViewModel.uiStateFlow.collect { state ->
                when (state) {
                    MainActivityState.BigMap_MiniFpv -> {
                        TransitionManager.beginDelayedTransition(mBinding.mainLayout)
                        buildToggleMapAndFpvView(mBinding.mainLayout, mBinding.frameLayoutMap.id, mBinding.frameLayoutFpv.id, null).applyTo(mBinding.mainLayout)
                        EventBus.getDefault().post(ToggleMapSize(ToggleSize.BIG))
                        EventBus.getDefault().post(ToggleFpvSize(ToggleSize.MINI))
                    }
                    MainActivityState.BigFpv_IconMap -> {
                        TransitionManager.beginDelayedTransition(mBinding.mainLayout)
                        buildToggleMapAndFpvView(mBinding.mainLayout, mBinding.frameLayoutFpv.id, null, mBinding.frameLayoutMap.id).applyTo(mBinding.mainLayout)
                        EventBus.getDefault().post(ToggleMapSize(ToggleSize.ICON))
                        EventBus.getDefault().post(ToggleFpvSize(ToggleSize.BIG))
                    }
                    MainActivityState.BigFpv_MiniMap -> {
                        TransitionManager.beginDelayedTransition(mBinding.mainLayout)
                        buildToggleMapAndFpvView(mBinding.mainLayout, mBinding.frameLayoutFpv.id, mBinding.frameLayoutMap.id, null).applyTo(mBinding.mainLayout)
                        EventBus.getDefault().post(ToggleMapSize(ToggleSize.MINI))
                        EventBus.getDefault().post(ToggleFpvSize(ToggleSize.BIG))
                    }
                }
                rebindFcStatusView().applyTo(mBinding.mainLayout)
                assignmentViewDisplayLevel(state)
            }
        }
    }

    private fun displayRlControlMenuSelectorDialog(items: MutableList<Pair<String, String>>) {
        showCenterSelectDialogWithType(this, object : OnDialogSelectWithTypeListener<String>{
            override fun onResult(index: Int, keyword: String, type: String) {
                //保存当前类型，下次初始化使用
                mViewModel.sendUiIntent(MainActivityIntent.SaveRlMenuItemSelected(type))
                //添加选中的控制类
                replaceFragment(R.id.frameLayoutRl, type, R.anim.rl_fragment_in, R.anim.rl_fragment_out)
            }
        },
            getString(R.string.main_rl_menu_title),
            items.map { it.first }.toMutableList(),
            items.map { it.second }.toMutableList())
    }

    private fun displayLbControlMenuSelectorDialog(items: MutableList<Pair<String, String>>) {
        showCenterSelectDialogWithType(this, object : OnDialogSelectWithTypeListener<String>{
            override fun onResult(index: Int, keyword: String, type: String) {
                //保存当前类型，下次初始化使用
                mViewModel.sendUiIntent(MainActivityIntent.SaveLbMenuItemSelected(type))
                //添加选中的控制类
                replaceFragment(R.id.frameLayoutStatus, type)
            }
        },
            getString(R.string.main_lb_menu_title),
            items.map { it.first }.toMutableList(),
            items.map { it.second }.toMutableList())
    }

    private fun replaceFragment(layoutID: Int, routerPath: String, animIn: Int = -1, animOut: Int = -1) {
        if (routerPath.isEmpty()) {
            //隐藏
            findViewById<View>(layoutID).gone()
            fragmentManager {
                supportFragmentManager.findFragmentById(layoutID)?.let { remove(it) }
            }
        } else {
            //显示
            findViewById<View>(layoutID).visible()
            if (animIn == -1 && animOut == -1) {
                replaceFragment(
                    layoutID,
                    ARouter.getInstance().build(routerPath).navigation() as Fragment
                )
            } else {
                replaceFragment(
                    layoutID,
                    ARouter.getInstance().build(routerPath).navigation() as Fragment,
                    animIn,
                    animOut,
                    null
                )
            }
        }
    }

    private fun assignmentViewDisplayLevel(state: MainActivityState) {
        //重新分配view层级关系
        mBinding.frameLayoutTl.z = 50.0f
        mBinding.rlLayout.z = 50.0f
        mBinding.frameLayoutFcStatus.z = 50.0f
        mBinding.frameLayoutHms.z = 50.0f
        mBinding.frameLayoutObstacle.z = 30.0f
        mBinding.frameLayoutStatus.z = 30.0f
        mBinding.frameLayoutOther.z = 20.0f
        when (state) {
            MainActivityState.BigFpv_IconMap -> {
                mBinding.frameLayoutMap.z = 90.0f
                mBinding.frameLayoutFpv.z = 10.0f
            }
            MainActivityState.BigFpv_MiniMap -> {
                mBinding.frameLayoutMap.z = 90.0f
                mBinding.frameLayoutFpv.z = 10.0f
            }
            MainActivityState.BigMap_MiniFpv -> {
                mBinding.frameLayoutFpv.z = 90.0f
                mBinding.frameLayoutMap.z = 10.0f
            }
        }
    }

    private fun rebindFcStatusView(): ConstraintSet {
        //重新绑定飞行信息栏目的左侧view绑定关系
        return ConstraintSet().also {
            it.clone(mBinding.mainLayout)
            it.clear(mBinding.frameLayoutFcStatus.id)
            it.constrainWidth(mBinding.frameLayoutFcStatus.id, ConstraintSet.WRAP_CONTENT)
            it.constrainHeight(mBinding.frameLayoutFcStatus.id, ConstraintSet.WRAP_CONTENT)
            when (mViewModel.uiStateFlow.value) {
                MainActivityState.BigFpv_IconMap, MainActivityState.BigFpv_MiniMap -> {
                    it.connect(mBinding.frameLayoutFcStatus.id, ConstraintSet.LEFT, mBinding.frameLayoutMap.id, ConstraintSet.RIGHT, px2dp(64.0f))
                }
                MainActivityState.BigMap_MiniFpv -> {
                    it.connect(mBinding.frameLayoutFcStatus.id, ConstraintSet.LEFT, mBinding.frameLayoutFpv.id, ConstraintSet.RIGHT, px2dp(64.0f))
                }
            }
            it.connect(mBinding.frameLayoutFcStatus.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, px2dp(64.0f))
        }
    }

    private fun buildToggleMapAndFpvView(mainID: ConstraintLayout, bigID: Int, miniID: Int?, iconID: Int?): ConstraintSet {
        if (miniID == null && iconID == null) return ConstraintSet()

        return ConstraintSet().also { set ->
            //copy parent layout
            set.clone(mainID)
            set.clear(bigID)
            val tmpLayout = miniID ?: iconID!!
            set.clear(tmpLayout)
            //build first view
            set.constrainWidth(bigID, ConstraintSet.MATCH_CONSTRAINT)
            set.constrainHeight(bigID, ConstraintSet.MATCH_CONSTRAINT)
            set.connect(bigID, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT, 0)
            set.connect(bigID, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0)
            set.connect(bigID, ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 0)
            set.connect(bigID, ConstraintSet.TOP, mBinding.frameLayoutTl.id, ConstraintSet.TOP, 0)
            //build second
            set.constrainWidth(tmpLayout, ConstraintSet.MATCH_CONSTRAINT)
            set.constrainHeight(tmpLayout, ConstraintSet.MATCH_CONSTRAINT)
            set.connect(tmpLayout, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT, px2dp(64.0f))
            set.connect(tmpLayout, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, px2dp(64.0f))
            iconID?.let {
                set.constrainPercentWidth(it, 0.05f)
                set.setDimensionRatio(it, "H,1:1")
            }
            miniID?.let {
                set.constrainPercentWidth(it, 0.25f)
                set.setDimensionRatio(it, "H,16:9")
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventBus(event: OnMapTouchEvent) = mViewModel.sendUiIntent(MainActivityIntent.ToggleMapAndFpvView(System.currentTimeMillis()))

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventBus(event: OnHmsFlexVisibility) { mBinding.frameLayoutHms.visibility = event.isVisibility }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventBus(event: OnStatusMenuClickEvent) = mViewModel.sendUiIntent(MainActivityIntent.ShowStatusMenuItemSelectorDialog)
}